package com.atguigu.servicebase.exceptionhandler;

import com.atguigu.commonutils.R;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.validator.internal.engine.ConstraintViolationImpl;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.validation.ConstraintViolationException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * @Author chenyeqing
 * @Date 2021/12/24 23:39
 */
@ControllerAdvice
@Slf4j
public class GlobalException {


    // 指定出现什么异常执行这个方法
    @ExceptionHandler(Exception.class)
    // 为了能够返回数据
    @ResponseBody
    /**
     * 统一异常处理
     * @param e
     * @return
     */
    public R error(Exception e) {
        log.error(e.getMessage(), e);
        return R.error().message("执行了全局异常处理...");
    }

    @ExceptionHandler(ArithmeticException.class)
    @ResponseBody
    public R error(ArithmeticException e) {
        log.error(e.getMessage(), e);
        return R.error().message("执行了ArithmeticException异常处理...");
    }

    @ExceptionHandler(GuliException.class)
    @ResponseBody
    public R error(GuliException e) {
        log.error(e.getMessage(), e);
        return R.error().code(e.getCode()).message(e.getMsg());
    }

    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    @ResponseBody
    public R error(MethodArgumentNotValidException e) {
        Map<String, Object> map = new HashMap<>();
        e.getBindingResult().getAllErrors().forEach((error) -> {
            String fieldName = ((FieldError) error).getField();
            String errorMessage = error.getDefaultMessage();
            map.put(fieldName, errorMessage);
        });
        log.error(e.getMessage(), e);
        return R.error().data(map);
    }

    @ExceptionHandler(value = ConstraintViolationException.class)
    @ResponseBody
    public R error(ConstraintViolationException e) {
        log.error(e.getMessage(), e);
        Set errors = e.getConstraintViolations();
        Map<String, Object> errorMap = new HashMap<>();
        errors.forEach((error) -> {
            errorMap.put("入参错误", ((ConstraintViolationImpl) error).getMessage());
        });
        return R.error().data(errorMap);
    }

}
